package com.zhenai.lancering.controller;

import android.content.Context;
import android.os.Environment;

import com.kantarmedia.syncnow.SyncNowDetector;
import com.kantarmedia.syncnow.SyncNowDetector.WatermarkDetectorConfiguration;
import com.kantarmedia.syncnow.SyncNowDetectorFactory;
import com.kantarmedia.syncnow.SyncNowDetectorListener;
import com.zhenai.lancering.model.AudioConfiguration;
import com.zhenai.lancering.model.DetectorConfiguration;

import java.io.File;


public class AudioDetector implements SyncNowDetectorListener {
    private static final String TAG = "sync.AudioDetector";
    private static final String BASE_FILE_NAME = Environment.getExternalStorageDirectory() + File.separator + "SyncNowDetector";
    private SyncNowDetector mDetectorSDK;
    private DetectorConfiguration mDetectorConfig;

    public AudioDetector(Context context, AudioConfiguration audioConfig, DetectorConfiguration detectorConfig) {
        super();
        mDetectorConfig = detectorConfig;

        WatermarkDetectorConfiguration detectorConfiguration = new WatermarkDetectorConfiguration();
        detectorConfiguration.audioParameters.sampleRate = audioConfig.mSampleRate;
        detectorConfiguration.audioParameters.numBitsPerChannel = audioConfig.mNumBitsPerChannel;
        detectorConfiguration.audioParameters.numChannels = audioConfig.mNumChannels;
        detectorConfiguration.audioParameters.buffLength = audioConfig.mBufferSize;
        detectorConfiguration.algorithmParameters.mode = SyncNowDetector.MODE_LIVE;
        detectorConfiguration.algorithmParameters.numIdentifierBits = detectorConfig.numIdentifierBits;
        detectorConfiguration.algorithmParameters.numTimeStampBits = detectorConfig.numTimeStampBits;
        // Setting the license is mandatory to enable the detection.
        // This is where the detection technology (SyncNow 2G, SyncNow 3G, SNAP or Ink) is configured.
        detectorConfiguration.algorithmParameters.license = detectorConfig.license;
        // Set the listener instance to receive the SDK notification events: onPayload(), onDebug() and onAlarm()
        detectorConfiguration.algorithmParameters.listener = this;

        // Logging detection events in file
        if (detectorConfig.logEnabled) {
            String fileNameLog = getNextAvailableFileName(BASE_FILE_NAME, ".txt");
            if (null != fileNameLog) {
                onDebug("set logFileName:" + fileNameLog);
                detectorConfiguration.extraParameters.logFileName = fileNameLog;
            }
        }
        // Record input audio
        if (detectorConfig.recordEnabled) {
            String inputAudioRecordFileName = getNextAvailableFileName(BASE_FILE_NAME, ".wav");
            if (null != inputAudioRecordFileName) {
                onDebug("set inputAudioRecordFileName:" + inputAudioRecordFileName);
                detectorConfiguration.extraParameters.recordFileName = inputAudioRecordFileName;
            }
        }
        // Instantiate the SyncNow Detector SDK with the create factory API.
        // This instance is the SDK entry point to access the detection API.
        StringBuilder resultString = new StringBuilder();
        // Instantiate the SDK detector
        mDetectorSDK = SyncNowDetectorFactory.createSyncNowDetector(context, detectorConfiguration, resultString);
        if (null == mDetectorSDK) {
            // irrecoverable error: the SDK can not be instantiated
            onError(-1, resultString.toString());
        }
        //default mode
        if (resultString.toString().equals("AWM_DEFAULT_DETECTOR")) {
            onDebug( resultString+" init failed. Check your license or contact Kantar Media support!");
        } else {
            onDebug(resultString+" create success");
        }
    }

    public String getVersion() {
        return mDetectorSDK.getVersion();
    }

    public boolean getWatermarkPresence() {
        return mDetectorSDK.getWatermarkPresence();
    }

    public boolean getResetHistoricDetection() {
        return mDetectorSDK.resetHistoricDetection();
    }

    public boolean pushAudioBuffer(byte audioSampleBuffer[], int audioSampleBufferSize) {
        return mDetectorSDK.pushAudioBuffer(audioSampleBuffer, audioSampleBufferSize);
    }

    public void stop() {
        SyncNowDetectorFactory.destroy(mDetectorSDK);
    }

    @Override
    public void onDebug(String text) {

    }

    @Override
    public void onPayload(PayloadEvent event) {

    }

    @Override
    public void onAlarm(AlarmEvent event) {

    }

    public void onError(int code, String msg) {

    }

    /**
     * Computes the next available file name.
     * <p>
     * This is an helper method to compute the next available
     * file names for the logs and the audio input recording.
     *
     * @param firstFileName the file name of the first file to create
     * @return the next available file name
     */
    private String getNextAvailableFileName(String firstFileName, String extension) {
        String nextValidName;
        int numFile = 1;
        File file;

        // Loop till a non used file name is found
        do {
            nextValidName = firstFileName + "_" + mDetectorConfig.instName + "_" + numFile + extension;
            file = new File(nextValidName);
            numFile++;
        } while (file.exists());

        @SuppressWarnings("unused")
        boolean deleted = file.delete();
        return nextValidName;
    }
}
